package vip.george.realm;

import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
import vip.george.entity.User;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author gehaodong
 * @since 2024/3/11
 * <p>
 *     继承了AuthenticatingRealm，实现了自定义的认证功能
 * </P>
 */
public class MyRealm01 extends AuthenticatingRealm {
    private final Map<String, User> userMap = new HashMap<>();

    public MyRealm01() {
        userMap.put("tom", new User(1, "tom", "tom123"));
        userMap.put("jerry", new User(2, "jerry", "jerry123"));
    }

    /**
     * <p>认证时核心的方法</p>
     * <p>这个方法就干一件事：根据<strong>用户输入的用户名</strong>去数据库查询用户信息并返回</p>
     * <p>至于密码的校验，后续shiro会自动对比</p>
     * @param token 参数是用户登录时输入的用户名和密码等信息
     * @return 返回的是从数据库中查询到的真实用户信息
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        // 获取用户登陆输入的用户名
        String username = usernamePasswordToken.getUsername();
        User userFromDB = selectUserFromDB(username);
        if (Objects.isNull(userFromDB)) {
            throw new UnknownAccountException("用户名输入错误");
        }
        // 如果通过数据库查询到了用户，就返回给shiro一个封装了用户信息的AuthenticationInfo对象
        return new SimpleAuthenticationInfo(userFromDB.getUsername(), userFromDB.getPassword(), getName());
    }


    /**
     * 模拟通过用户名从数据库中查询数据
     * @return
     */
    private User selectUserFromDB(String username) {
        return userMap.get(username);
    }
}
